<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>

<!DOCTYPE html>
<html>
	<head>
		<title>Infoviz - Twitter</title>
		<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script>
		<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.8.18/jquery-ui.min.js"></script>
		<script src="lib/jquery.timer.js"></script>
		<script type="text/javascript" src="http://www.google.com/jsapi"></script>
    	<script type="text/javascript">
      		google.load('visualization', '1.1', {packages: ['corechart', 'controls'], 'language': 'es'});
    	</script>
		<link type="text/css" rel="stylesheet" href="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8/themes/base/jquery-ui.css"></link>
		<script type="text/javascript">
			var updateFreq = 10;
			var groupingFreq = 10;
			var includeResponse = true;
			var includeRetweets = true;
			var minFollowers = 0;
			var data;
			var dashboard;
			var chart;
			var barsLoaded = false;
			var control;
			var colors2 = [];
			var maxDate;
			var minDate;
			var barsDataTable = new google.visualization.DataTable();
			var dataTable;
			var dataDetails;
			var itemSelected;
			var isStacked = false;
			var colors = ['#FF0000','#00FF00','#0000FF','#FFFF00','#FF00FF'];
			var timer = $.timer(updateData, updateFreq*1000);
			var selectedSubject = [];
			var numberChecked = 0;
		
			$(document).ready(function() {
				$(".subjects_check").map(function(){ numberChecked++;});
				
				$(".subjects_check").click(function() {
					if($(this).is(':checked')) {
						++numberChecked;
						if(numberChecked>1) {
							$(".subjects_check").map(function(){
								if($(this).is(':checked')) {
									$(this).attr("disabled", false);
								}
							});
						}
					}
					else {
						--numberChecked;
						if(numberChecked==1) {
							$(".subjects_check").map(function(){
								if($(this).is(':checked')) {
									$(this).attr("disabled", true);
								}
							});
						}
					}
					updateViz();
				});
				
		    	$("#freq-slider").slider({min:0, max:3, step:0, slide:
		    		function(event,ui) {
		    			var secsArray = [10, 30, 60, 120];
		    			var secs = secsArray[ui.value];
		    			if(secs==60) {
		    				$("#freq-value").text(1);
		    				$("#freq-value-unit").text("minuto");
		    			}
		    			else if(secs==120) {
		    				$("#freq-value").text(2);
		    				$("#freq-value-unit").text("minutos");
		    			}
		    			else {
		    				$("#freq-value").text(secs);
		    				$("#freq-value-unit").text("segundos");
		    			}
		    			updateFreq = secs;
		    			setTimer();
		    		}	
		    	});
		    	
		    	$("#grouping-slider").slider({min:0, max:5, step:0, slide:
		    		function(event,ui) {
		    			var secsArray = [10, 30, 60, 300, 420, 600];
		    			var secs = secsArray[ui.value];
		    			if(secs==60) {
		    				$("#grouping-value").text(1);
		    				$("#grouping-value-unit").text("minuto");
		    			}
		    			else if(secs==300) {
		    				$("#grouping-value").text(5);
		    				$("#grouping-value-unit").text("minutos");
		    			}
		    			else if(secs==420){
		    				$("#grouping-value").text(7);
		    				$("#grouping-value-unit").text("minutos");
		    			}
		    			else if(secs==600){
		    				$("#grouping-value").text(10);
		    				$("#grouping-value-unit").text("minutos");
		    			}
		    			else {
		    				$("#grouping-value").text(secs);
		    				$("#grouping-value-unit").text("segundos");
		    			}
		    			groupingFreq = secs;
		    			updateData();
		    		}	
		    	});
		    	
		    	$("#include-response").bind('change',function (){
					if($(this).is(':checked')) {
						includeResponse = true;
					}
					else {
						includeResponse = false;
					}
					updateData();
				});
				
				$("#include-retweets").bind('change',function (){
					if($(this).is(':checked')) {
						includeRetweets = true;
					}
					else {
						includeRetweets = false;
					}
					updateData();
				});
				
				$("#min-followers").change(function(){
					minFollowersAux = $(this).val();
					var regExp = new RegExp("^[0-9]+$");
					if(minFollowersAux==null || minFollowersAux=='' || !regExp.test(minFollowersAux)) {
						$("#err-msg-minfol").toggle(true);
					}
					else {
						$("#err-msg-minfol").toggle(false);
						minFollowers = minFollowersAux;
						updateData();
					}
				});
				
				timer.play();
				$("#err-msg-minfol").toggle(false);
				$("#dataLookup").toggle(true);
				updateData();
		  	});
			
			function updateData() {
				var arguments;
				arguments.minFollowers = minFollowers;
				arguments.includeRetweets = includeRetweets;
				arguments.includeResponse = includeResponse;
				arguments.groupingFreq = groupingFreq;
				arguments.updateFreq = 86400;
				
				$.get("mainData", arguments, function(response) {
					data = $.parseJSON(response);
					updateViz();
				}, 'text');
			}
			
			function setTimer() {
				timer.stop();
				timer.set({ time: updateFreq * 1000 });
				timer.reset();
				timer.play();
				updateData();
			}
			
			function drawVisualization() {
				dashboard = new google.visualization.Dashboard(document.getElementById('dashboard'));
			    
				control = new google.visualization.ControlWrapper({
					'controlType': 'ChartRangeFilter',
					'containerId': 'control',
					'options': {
				    	// Filter by the date axis.
				    	'filterColumnIndex': 0,
				    	'ui': {
				      		'chartType': 'LineChart',
				      		'chartOptions': {
				        		'chartArea': {'width': '90%'},
				        		'hAxis': {'baselineColor': 'none'}
				      		},
						    // Display a single series that shows the closing value of the stock.
						    // Thus, this view has two columns: the date (axis) and the stock value (line series).
						    'chartView': {
						    	'columns': [0, 1, 2]
						    },
				      		'minRangeSize': 1000
				    	}
				  	},
				  	'state': {'range': {'start': new Date(2012, 1, 9,1,1,1), 'end': new Date(2013, 11, 20,1,1,1)}}
				});

				chart = new google.visualization.ChartWrapper({
					'chartType': 'LineChart',
				  	'containerId': 'chart',
				  	'options': {
					    // Use the same chart area width as the control for axis alignment.
					    'chartArea': {'height': '80%', 'width': '90%'},
					    'hAxis': {'slantedText': false},
					    //'vAxis': {'viewWindow': {'min': 0, 'max': 2000}},
					    'legend': {'position': 'none'}
				  	},
				  	// Convert the first column from 'date' to 'string'.
				  	// Just show column 1 and 2
				  	'view': {
				    	'columns': [
				      	{
				        	'calc': function(dataTable, rowIndex) {
				          		return dataTable.getFormattedValue(rowIndex, 0);
				       		},
				        'type': 'string'
				      	}, 1,2]
				  	}
				});
			}
			
			function updateViz() {
				loadBars();
				dataTable = new google.visualization.DataTable();
				dataDetails = new google.visualization.DataTable();
				//dataDetails.addColumn('string','sample');
				var subjectsInfo = [];
				var i=1;
				var length = 0;
				dataTable.addColumn('datetime','Fecha');
				var j = 1;
				for(var sub in data) {
					dataTable.addColumn('number',sub);
					dataDetails.addColumn('string','Details '+i);
					subjectsInfo[i++]=sub;
					length = data[sub].length;
					++i;
					j++;
				}
				
				i=0;
				var row = [];
				var details = new Array();
				var prevMaxDate = maxDate;
				minDate = new Date(2025,1,1,1,1,1,1);
				maxDate = new Date(1900,1,1,1,1,1,1);
				
				var j = 1;
				for(var tag in data) {
					barsDataTable.setCell(0, j, 0);
					j++;
				} 
				
				for(var j=1, k=1;j<length;++j,k=1) {
					var tag = 1;
					for(var sub in data) {
						if((data[sub])[j]!==undefined){
							row[0] = new Date((data[sub])[j].date)
							if(row[0]<minDate) {
								minDate=row[0];
							}
							if(row[0]>maxDate) {
								maxDate=row[0];
							}
							barsDataTable.setCell(0, tag, barsDataTable.getValue(0, tag) + (data[sub])[j].amount);
							tag++;
							row[k] = (data[sub])[j].amount;
							var arr = new Array((data[sub])[j].amount,(data[sub])[j].retweets,(data[sub])[j].replys);
							//var str = (data[sub])[j].amount+', '+(data[sub])[j].retweets', '+(data[sub])[j].replys;
							details[k-1]= arr.join(", ");
						}
						else {
							var arr = new Array(0,0,0);
							details[k-1]= arr.join(", ");
							row[k] = 0;
						}
						++k;
					}
					dataTable.addRow(row);
					dataDetails.addRow(details);
				}
				
				var state = control.getState('state');
			    if(state==null) {
			    	state = {'range': {'start': new Date(2012, 1, 9,1,1,1), 'end': new Date(2013, 11, 20,1,1,1)}};
			    }	
				if(state.range.end>=prevMaxDate) {
			    	state.range.end=maxDate;
			    }
			    
				var columns = getSelectedSubjects();
				
				var columns1 = [0];
				for(var i=0;i<columns.length;++i) {
					columns1.push(columns[i]);
				}
				
				var columns2 = [{
		        	'calc': function(dataTable, rowIndex) {
		          		return dataTable.getFormattedValue(rowIndex, 0);
		       		},
		        	'type': 'string'
		      	}];
				
				for(var i=0;i<columns.length;++i) {
					columns2.push(columns[i]);
				}
				
				for(var i=0;i<columns.length;++i) {
					colors2.push(colors[columns[i]-1]);
				}
				
				// Si no hay al menos de dos puntos no muestro nada.
				if(dataTable.getNumberOfRows()<2) {
					return;
				}
				dashboard = new google.visualization.Dashboard(document.getElementById('dashboard'));
			    
				control = new google.visualization.ControlWrapper({
					'controlType': 'ChartRangeFilter',
					'containerId': 'control',
					'options': {
				    	// Filter by the date axis.
				    	'filterColumnIndex': 0,
				    	'ui': {
				      		'chartType': 'LineChart',
				      		'chartOptions': {
				        		'chartArea': {'width': '90%'},
				        		'hAxis': {'baselineColor': 'none'},
				        		'colors': colors2
				      		},
						    // Display a single series that shows the closing value of the stock.
						    // Thus, this view has two columns: the date (axis) and the stock value (line series).
						    'chartView': {
						    	'columns': columns1
						    },
				      		// 1 day in milliseconds = 24 * 60 * 60 * 1000 = 86,400,000
				      		'minRangeSize': 100
				    	}
				  	},
				  	'state': state
				  	
				});
				
				chart = new google.visualization.ChartWrapper({
					'chartType': 'LineChart',
				  	'containerId': 'chart',
				  	'options': {
					    // Use the same chart area width as the control for axis alignment.
					    'chartArea': {'height': '80%', 'width': '80%'},
					    'hAxis': {'slantedText': false},
					    'vAxis': {'title':'Tweets por segundo [Tps]','format':'#'},
					    'pointSize' : 3,
					    'legend' : {'position': 'none'},
					    'colors': colors2
				  	},
				  	// Convert the first column from 'date' to 'string'.
				  	// Just show column 1 and 2
				  	'view': {
				    	'columns': columns2
				  	}
				});
				
				dashboard.bind(control, chart);
		        dashboard.draw(dataTable);
		        $("#dataLookup").toggle(false);
				google.visualization.events.addListener(chart, 'ready', chartReady);
				drawChart();
				
			}
			
			function getSelectedSubjects() {
				var columns = [];
				var allVals = [];
			    $('#checkboxes :checked').each(function() {
			    	allVals.push($(this).val());
			    });
			    
			    allVals = allVals.map(function(elem) { return elem.toLowerCase(); }); 

			    for(var i=1;i<dataTable.getNumberOfColumns();++i) {
			    	for(var j=0;j<allVals.length;++j) {
			    		if(allVals[j]==dataTable.getColumnLabel(i).toLowerCase()) {
			    			columns.push(i);
			    		}
			    	}
				}
				return columns;
			}
			
			function chartReady() {
				google.visualization.events.addListener(chart.getChart(), 'select', dotSelected);
			}
			
			function dotSelected(){
				itemSelected = chart.getChart().getSelection()[0];
				var data2 = chart.getDataTable();
				var baseRowIndex = data2.getTableRowIndex(itemSelected.row);
				var baseColumnIndex = data2.getTableColumnIndex(itemSelected.column);
				dotSelectedAux(baseRowIndex, baseColumnIndex);
			}
			
			function dotSelectedAux(baseRowIndex, baseColumnIndex) {
				var detail = dataDetails.getValue(baseRowIndex,baseColumnIndex-1);
				var splitted = detail.split(", ");
				var amount = parseInt(splitted[0]);
				var retweets = parseInt(splitted[1]);
				var replys = parseInt(splitted[2]);
				var others = amount - retweets - replys;
				var detailedData = google.visualization.arrayToDataTable([
					['Type', 'Amount'],
					['Retweets', retweets],
					['Normal tweets', others],
					['Replys', replys]
				]);
				var chart = new google.visualization.PieChart(document.getElementById('pie'));
				chart.draw(detailedData,{'pieSliceText': 'value', 'sliceVisibilityThreshold': 0});
			}
			
	      	google.setOnLoadCallback(drawVisualization);
	      	
	      	
	         
	      	function drawChart() {   
	      		if(!barsLoaded){
	      			loadBars();
	      		}
	      		var options = {
   	             	title: 'Total de Tweets',
   	             	vAxis: {textPosition: "none"},
   	             	hAxis: {baseline: 0},
   	            	 colors: colors2,
   	          		isStacked: isStacked
   	           };

   	           var chart = new google.visualization.BarChart(document.getElementById('bars'));
   	           chart.draw(barsDataTable, options);
   	 //          chart.hideColumns(columnIndexes);
   	        	      		
	      	}
	      	
	      	function encimado(){
	      		isStacked = !isStacked;
	      		drawChart();
	      	}
	      	
	      	function loadBars() {
	      		if(barsLoaded){
	      			return;
	      		}
	      		barsLoaded = true;
				barsDataTable.addColumn('number', 'Tagg');
	           for(var tag in data) {
					barsDataTable.addColumn('number', tag);
				}
	        	barsDataTable.addRows(1);
	        	var j = 1;
	        	barsDataTable.setCell(0, 0, 0);
	        	for(var tag in data) {
					barsDataTable.setCell(0, j, 0);
					j++;
				} 
	      	}
	         
		</script>
	</head>
	<body>
		<h1  style='color:red; text-align: center'>TwitterViz</h1> 
		<div><span id="dataLookup" style='color:blue'>Por favor espere, recolectando datos...</span></div>
		
		<div id="dashboard" style="float:left; width:80%; height:100%">
        	<div id="chart" style='height: 500px;'></div>
        	<div id="control" style='height: 70px;'></div>
    	</div><br/>
	
		<div id="checkboxes" style="float:left; width:20%; height:100%">		
			<h2  style='color:blue'>Controles</h2>
			
			<div  style="display: none;">
		 	<c:forEach var="subject" items="${subjects}">
				<span class="subjects_label"><c:out value="${subject}"/>:</span> <input type="checkbox" class="subjects_check" value="<c:out value="${subject}"/>" checked><br/>
			</c:forEach>
			</div>
			 
			
			<label><b>Frecuencia de actualizacion</b></label>: <div id="freq-slider" style="width:200px"></div> <span id="freq-value">10</span> <span id="freq-value-unit">segundos</span><br/><br/>
			<label><b>Frecuencia de agrupamiento</b></label>:<div id="grouping-slider" style="width:200px"></div> <span id="grouping-value">10</span> <span id="grouping-value-unit">segundos</span><br/><br/>
			<label><b>Cantidad de seguidores:</b></label><br/>
			<input id="min-followers" type="text" value="0"/><br/>
			<span id="err-msg-minfol" style="color:red;">El valor ingresado no es correcto</span><br/>

			<b><input type="checkbox" value="encimado" onchange="encimado();"> 
			<label>Stacked</label></b>
		</div>
		
		<div id="details" style="float:left; width:20%; height:50%">
			<div id="pie"></div>
		</div>


		<div id="bars" style="float:left; width:100%; height:100%"/>
	</body>
</html>